
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多难度数字华容道</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        .tile {
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        .tile:hover {
            transform: scale(1.05);
            box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
        }
        .empty {
            visibility: hidden;
        }
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        .fade-in {
            animation: fadeIn 0.5s ease-in;
        }
        .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
        .grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
        .grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
    </style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-purple-50 min-h-screen">
    <div class="container mx-auto px-4 py-8">
        <header class="text-center mb-8">
            <h1 class="text-4xl font-bold text-purple-800 mb-2">多难度数字华容道</h1>
            <p class="text-gray-600">选择难度挑战你的逻辑思维能力</p>
        </header>

        <div class="max-w-2xl mx-auto bg-white rounded-xl shadow-lg overflow-hidden p-6 mb-8">
            <div class="flex flex-wrap justify-between items-center mb-6 gap-4">
                <div class="flex space-x-2">
                    <button id="easy-btn" class="difficulty-btn bg-green-500 hover:bg-green-600" data-size="3">
                        3×3 简单模式
                    </button>
                    <button id="medium-btn" class="difficulty-btn bg-yellow-500 hover:bg-yellow-600" data-size="4">
                        4×4 标准模式
                    </button>
                    <button id="hard-btn" class="difficulty-btn bg-red-500 hover:bg-red-600" data-size="5">
                        5×5 困难模式
                    </button>
                </div>
                <div class="flex items-center space-x-4">
                    <div class="text-lg font-semibold text-gray-700">
                        <i class="fas fa-clock mr-2 text-purple-600"></i>
                        <span id="timer">00:00</span>
                    </div>
                    <div class="text-lg font-semibold text-gray-700">
                        <i class="fas fa-shoe-prints mr-2 text-purple-600"></i>
                        <span id="moves">0</span> 步
                    </div>
                </div>
            </div>

            <div id="puzzle-container" class="grid gap-3 mb-6 bg-purple-100 p-3 rounded-lg min-h-[20rem] items-center justify-center">
                <p class="text-center text-gray-500">请选择游戏难度开始挑战</p>
            </div>

            <div class="flex flex-wrap justify-between gap-2">
                <button id="shuffle-btn" class="action-btn bg-purple-600 hover:bg-purple-700" disabled>
                    <i class="fas fa-random mr-2"></i>打乱
                </button>
                <button id="solve-btn" class="action-btn bg-green-600 hover:bg-green-700" disabled>
                    <i class="fas fa-lightbulb mr-2"></i>提示
                </button>
                <button id="new-game-btn" class="action-btn bg-blue-600 hover:bg-blue-700" disabled>
                    <i class="fas fa-redo mr-2"></i>新游戏
                </button>
            </div>
        </div>

        <div id="win-message" class="hidden max-w-md mx-auto bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-8 rounded">
            <div class="flex items-center">
                <i class="fas fa-trophy text-2xl mr-3 text-yellow-500"></i>
                <div>
                    <p class="font-bold">恭喜你赢了!</p>
                    <p>用时: <span id="win-time"></span>, 步数: <span id="win-moves"></span></p>
                </div>
            </div>
        </div>

        <div class="max-w-2xl mx-auto grid md:grid-cols-2 gap-6">
            <div class="bg-white rounded-xl shadow-lg overflow-hidden p-6">
                <h2 class="text-xl font-bold text-purple-800 mb-4">游戏规则</h2>
                <ul class="list-disc pl-5 text-gray-700 space-y-2">
                    <li>点击数字方块可以将其移动到空白位置</li>
                    <li>目标是将数字按顺序排列</li>
                    <li>空白方块位于右下角时为胜利</li>
                    <li>使用最少步数和最短时间完成挑战</li>
                </ul>
            </div>
            <div class="bg-white rounded-xl shadow-lg overflow-hidden p-6">
                <h2 class="text-xl font-bold text-purple-800 mb-4">难度说明</h2>
                <ul class="list-disc pl-5 text-gray-700 space-y-2">
                    <li><span class="font-semibold">3×3简单模式</span>：适合初学者，排列1-8数字</li>
                    <li><span class="font-semibold">4×4标准模式</span>：经典难度，排列1-15数字</li>
                    <li><span class="font-semibold">5×5困难模式</span>：高阶挑战，排列1-24数字</li>
                </ul>
            </div>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const puzzleContainer = document.getElementById('puzzle-container');
            const timerElement = document.getElementById('timer');
            const movesElement = document.getElementById('moves');
            const shuffleBtn = document.getElementById('shuffle-btn');
            const solveBtn = document.getElementById('solve-btn');
            const newGameBtn = document.getElementById('new-game-btn');
            const winMessage = document.getElementById('win-message');
            const winTimeElement = document.getElementById('win-time');
            const winMovesElement = document.getElementById('win-moves');
            const difficultyBtns = document.querySelectorAll('.difficulty-btn');

            let tiles = [];
            let emptyIndex = 0;
            let moves = 0;
            let seconds = 0;
            let timer;
            let isGameRunning = false;
            let gridSize = 0;
            let tileSizeClass = '';

            // 初始化游戏
            function initGame(size) {
                gridSize = size;
                tileSizeClass = `grid-${size}`;
                puzzleContainer.className = `grid gap-3 mb-6 bg-purple-100 p-3 rounded-lg ${tileSizeClass}`;
                
                const totalTiles = size * size - 1;
                tiles = Array.from({ length: totalTiles }, (_, i) => i + 1);
                tiles.push(null); // 空白方块
                emptyIndex = tiles.length - 1;
                
                renderPuzzle();
                enableButtons();
            }

            // 渲染拼图
            function renderPuzzle() {
                puzzleContainer.innerHTML = '';
                tiles.forEach((num, index) => {
                    const tile = document.createElement('div');
                    tile.className = `tile flex items-center justify-center rounded-lg font-bold cursor-pointer ${num ? 'bg-white text-purple-800' : 'empty'}`;
                    
                    // 动态设置方块大小
                    if (gridSize === 3) {
                        tile.classList.add('h-24', 'text-3xl');
                    } else if (gridSize === 4) {
                        tile.classList.add('h-20', 'text-2xl');
                    } else {
                        tile.classList.add('h-16', 'text-xl');
                    }
                    
                    tile.textContent = num;
                    tile.dataset.index = index;
                    
                    if (num) {
                        tile.addEventListener('click', () => moveTile(index));
                    }
                    
                    puzzleContainer.appendChild(tile);
                });
            }

            // 移动方块
            function moveTile(clickedIndex) {
                if (!isGameRunning && moves === 0) {
                    startTimer();
                    isGameRunning = true;
                }

                const directions = [-1, 1, -gridSize, gridSize]; // 左,右,上,下
                for (const dir of directions) {
                    const targetIndex = clickedIndex + dir;
                    if (targetIndex === emptyIndex && isValidMove(clickedIndex, targetIndex)) {
                        // 交换位置
                        [tiles[clickedIndex], tiles[emptyIndex]] = [tiles[emptyIndex], tiles[clickedIndex]];
                        emptyIndex = clickedIndex;
                        moves++;
                        movesElement.textContent = moves;
                        renderPuzzle();
                        
                        if (checkWin()) {
                            endGame();
                        }
                        return;
                    }
                }
            }

            // 检查移动是否有效
            function isValidMove(clickedIndex, targetIndex) {
                // 检查是否在边界内
                if (targetIndex < 0 || targetIndex >= tiles.length) return false;
                
                // 检查是否在同一行(水平移动)
                if (Math.abs(clickedIndex - targetIndex) === 1 && 
                    Math.floor(clickedIndex / gridSize) === Math.floor(targetIndex / gridSize)) {
                    return true;
                }
                
                // 检查是否在同一列(垂直移动)
                if (Math.abs(clickedIndex - targetIndex) === gridSize) {
                    return true;
                }
                
                return false;
            }

            // 打乱拼图
            function shufflePuzzle() {
                resetGame();
                
                // 随机移动500次以确保可解
                for (let i = 0; i < 500; i++) {
                    const directions = [-1, 1, -gridSize, gridSize];
                    const validDirections = directions.filter(dir => {
                        const targetIndex = emptyIndex + dir;
                        return targetIndex >= 0 && targetIndex < tiles.length && 
                               isValidMove(targetIndex, emptyIndex);
                    });
                    
                    if (validDirections.length > 0) {
                        const randomDir = validDirections[Math.floor(Math.random() * validDirections.length)];
                        const targetIndex = emptyIndex + randomDir;
                        [tiles[targetIndex], tiles[emptyIndex]] = [tiles[emptyIndex], tiles[targetIndex]];
                        emptyIndex = targetIndex;
                    }
                }
                
                renderPuzzle();
                startTimer();
                isGameRunning = true;
            }

            // 检查是否获胜
            function checkWin() {
                for (let i = 0; i < tiles.length - 1; i++) {
                    if (tiles[i] !== i + 1) {
                        return false;
                    }
                }
                return tiles[tiles.length - 1] === null;
            }

            // 开始计时器
            function startTimer() {
                seconds = 0;
                updateTimer();
                timer = setInterval(() => {
                    seconds++;
                    updateTimer();
                }, 1000);
            }

            // 更新计时器显示
            function updateTimer() {
                const mins = Math.floor(seconds / 60).toString().padStart(2, '0');
                const secs = (seconds % 60).toString().padStart(2, '0');
                timerElement.textContent = `${mins}:${secs}`;
            }

            // 结束游戏
            function endGame() {
                clearInterval(timer);
                isGameRunning = false;
                winTimeElement.textContent = timerElement.textContent;
                winMovesElement.textContent = moves;
                winMessage.classList.remove('hidden');
                winMessage.classList.add('fade-in');
            }

            // 重置游戏状态
            function resetGame() {
                clearInterval(timer);
                moves = 0;
                seconds = 0;
                movesElement.textContent = '0';
                timerElement.textContent = '00:00';
                winMessage.classList.add('hidden');
                isGameRunning = false;
            }

            // 提示功能
            function showHint() {
                // 找出可以移动到空白位置的正确数字
                for (let i = 0; i < tiles.length; i++) {
                    if (tiles[i] === i + 1) continue; // 已经在正确位置
                    
                    if (tiles[i] && isValidMove(i, emptyIndex)) {
                        // 高亮显示可以移动的方块
                        const tile = puzzleContainer.children[i];
                        tile.classList.add('bg-yellow-200', 'animate-pulse');
                        setTimeout(() => {
                            tile.classList.remove('bg-yellow-200', 'animate-pulse');
                        }, 2000);
                        return;
                    }
                }
            }

            // 启用按钮
            function enableButtons() {
                shuffleBtn.disabled = false;
                solveBtn.disabled = false;
                newGameBtn.disabled = false;
            }

            // 事件监听
            shuffleBtn.addEventListener('click', shufflePuzzle);
            solveBtn.addEventListener('click', showHint);
            newGameBtn.addEventListener('click', () => {
                if (gridSize > 0) {
                    resetGame();
                    initGame(gridSize);
                }
            });

            // 难度选择
            difficultyBtns.forEach(btn => {
                btn.addEventListener('click', () => {
                    const size = parseInt(btn.dataset.size);
                    resetGame();
                    initGame(size);
                });
            });

            // 键盘控制
            document.addEventListener('keydown', (e) => {
                if (!isGameRunning || gridSize === 0) return;
                
                let targetIndex = -1;
                switch (e.key) {
                    case 'ArrowLeft':
                        targetIndex = emptyIndex + 1;
                        break;
                    case 'ArrowRight':
                        targetIndex = emptyIndex - 1;
                        break;
                    case 'ArrowUp':
                        targetIndex = emptyIndex + gridSize;
                        break;
                    case 'ArrowDown':
                        targetIndex = emptyIndex - gridSize;
                        break;
                }
                
                if (targetIndex >= 0 && targetIndex < tiles.length && isValidMove(targetIndex, emptyIndex)) {
                    moveTile(targetIndex);
                }
            });
        });
    </script>
</body>
</html>
